package com.jingdianjichi.subject.infra.basic.ES.SpringData版本.service.impl;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/*
@Service
@Slf4j
public class SubjectESServiceImpl implements SubjectESService {

    //都是去操作ES客户端的
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;            //他能操作文档和索引

    //和索引操作的我们就使用这个客户端,和数据操作的我们就使用我们自己定义的接口来交互

    @Resource
    private SubjectESRepository subjectESService;       //文档操作就是这个来做的     //只能做简单的文档操作

    @Override
    public void CreateIndex() {
        //创建索引
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(SubjectInfoES.class);

        indexOperations.create();   //就是去我们定义是实体类中的注解实现的,这里就是手动控制板了

        Document mapping = indexOperations.createMapping(SubjectInfoES.class);//这里就是根据你的索引创建Mapping的

        //把mapping放进来拿
        indexOperations.putMapping(mapping);
    }

    //插入文档
    @Override
    public void addDoc() {
        List<SubjectInfoES> list=new ArrayList<>();

        list.add(new SubjectInfoES(2L,"Redis是啥","redis是缓存","李思亮",new Date()));
        list.add(new SubjectInfoES(3L,"mysql是啥","mysql是数据库 ","李思亮",new Date()));

        //批量插入
        subjectESService.saveAll(list);
    }


    //查找文档亲
    @Override
    public void find() {
        Iterable<SubjectInfoES> all = subjectESService.findAll();

        for (SubjectInfoES subjectInfoES : all) {
            log.info("subjectInfoES:{}",subjectInfoES);
        }
    }

    //查找文档
    @Override
    public void search() {
        NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("subjectName","redis"))
                .build();       //这个就是查找subjectName列的,有redis的文档亲

        SearchHits<SubjectInfoES> search = elasticsearchRestTemplate.search(searchQuery, SubjectInfoES.class);

        List<SearchHit<SubjectInfoES>> hits = search.getSearchHits();

        log.info("hits:{}", JSON.toJSONString(hits));
    }

    /*
    1. ElasticsearchRestTemplate
    使用场景:

    复杂查询: 当你需要执行复杂的查询操作，比如聚合、过滤、排序等，ElasticsearchRestTemplate提供了更灵活的查询方式。你可以使用NativeSearchQuery和QueryBuilders来自定义查询。
    索引和映射操作: 当需要进行索引的创建、删除以及索引映射的配置时，ElasticsearchRestTemplate提供了方便的接口。
    批量操作: 此模板也支持批量操作，如批量索引、更新等。
    例子:

    java
    NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.matchQuery("subjectName", "redis"))
            .build();

    SearchHits<SubjectInfoES> search = elasticsearchRestTemplate.search(searchQuery, SubjectInfoES.class);
    2. SubjectESRepository
    使用场景:

    简单CRUD操作: 当你需要执行简单的CRUD（创建、读取、更新、删除）操作时，SubjectESRepository提供了基于Spring Data特性的简化方法，例如使用save和findAll等。
    自动化查询: 通过定义一些方法，SubjectESRepository可以直观地生成查询，而无需手动书写查询语句。例如，你可以根据方法名自动执行某些条件的查询。
    例子:

    java
    subjectESService.saveAll(list); // 批量插入文档
    Iterable<SubjectInfoES> all = subjectESService.findAll(); // 查找所有文档
    总结
    如果你的操作非常简单，比如直接增、删、查、改，那么使用SubjectESRepository是方便和直观的选择。
    如果你需要执行复杂的查询、索引操作或者更加灵活的文档操作，那么ElasticsearchRestTemplate是更合适的选择。


}
*/

